import {EffectComposer} from 'three/examples/jsm/postprocessing/EffectComposer.js'
import {RenderPass} from 'three/examples/jsm/postprocessing/RenderPass.js'
import {ShaderPass} from 'three/examples/jsm/postprocessing/ShaderPass.js'
import {OutlinePass} from 'three/examples/jsm/postprocessing/OutlinePass.js'
import {FXAAShader} from 'three/examples/jsm/shaders/FXAAShader.js'
import * as THREE from 'three'

class Outline {
  constructor(renderer, camera, scene) {
    const width = renderer.domElement.offsetWidth,
      height = renderer.domElement.offsetHeight
    renderer.domElement.style.touchAction = 'none'

    this.selectedObjects = []

    this.composer = new EffectComposer(renderer)

    this.renderPass = new RenderPass(scene, camera)
    this.composer.addPass(this.renderPass)

    this.outlinePass = new OutlinePass(new THREE.Vector2(width, height), scene, camera)
    this.outlinePass.selectedObjects = []
    this.composer.addPass(this.outlinePass)



    this.effectFXAA = new ShaderPass(FXAAShader)
    this.effectFXAA.uniforms.resolution.value.set(1 / width, 1 / height)
    this.composer.addPass(this.effectFXAA)

    this.render = (delta) => {
      this.composer.render(delta)
    }
  }

  setTexture(texture) {
    this.outlinePass.patternTexture = texture
    texture.wrapS = THREE.RepeatWrapping
    texture.wrapT = THREE.RepeatWrapping
  }

  useOne(object) {
    this.selectedObjects = []
    this.selectedObjects.push(object)
    this.outlinePass.selectedObjects = this.selectedObjects
  }

  add(object) {
    this.selectedObjects.push(object)
  }

  clear() {
    this.outlinePass.selectedObjects = []
  }

  updateAll(objects) {
    this.outlinePass.selectedObjects = objects
  }

  delByName(name) {
    this.outlinePass.selectedObjects.filter((object) => {
      return object.name !== name
    })
  }

  resetSize() {
    const width = this.renderer.domElement.offsetWidth,
      height = this.renderer.domElement.offsetHeight
    this.composer.setSize(width, height)
    this.effectFXAA.uniforms.resolution.value.set(1 / width, 1 / height)
  }

  setValues(params) {
    params = params || {}
    if (params.edgeStrength) this.outlinePass.edgeStrength = +params.edgeStrength
    if (params.edgeGlow) this.outlinePass.edgeGlow = +params.edgeGlow
    if (params.edgeThickness) this.outlinePass.edgeThickness = +params.edgeThickness
    if (params.pulsePeriod) this.outlinePass.pulsePeriod = +params.pulsePeriod
    this.outlinePass.usePatternTexture = params.usePatternTexture
    this.outlinePass.usePatternTexture = params.usePatternTexture
    if (params.visibleEdgeColor) this.outlinePass.visibleEdgeColor.set(params.visibleEdgeColor)
    if (params.hiddenEdgeColor) this.outlinePass.hiddenEdgeColor.set(params.hiddenEdgeColor)
  }
}

export default Outline